home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_209 / dps / dps.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  31KB  |  1,014 lines

  1. /*  DPS  V1.1
  2.  
  3. Author: Allen Norskog
  4.  
  5. Revision history:
  6.     V1.0:   3/28/89 - (unofficial release) 
  7.     V1.1:   4/23/89 - First real release 
  8.                     - bug fixes to V1.0
  9.                     - Allow Workbench startup
  10.  
  11. This program released into the Public Domain.
  12.  
  13. This program compiled with Manx Aztec C V3.6A using
  14. 32 bit integers.  (cc +L;  ln ... -lc32) */
  15.  
  16. #include <stdio.h>
  17. #include <exec/memory.h>
  18. #include <intuition/intuition.h>
  19. #include <intuition/screens.h>
  20. #include <graphics/display.h>
  21. #include <graphics/gfxmacros.h>
  22. #include <workbench/startup.h>
  23. #include <workbench/workbench.h>
  24. #include <workbench/icon.h>
  25. #include <functions.h>
  26.  
  27. FILE *fopen(),*ifile=NULL;
  28.  
  29.  
  30. #define ARG_REQ_NUM     1
  31. #define ARG_INFILE      1
  32.  
  33. #define ERR_NUM_ARGS    1
  34. #define ERR_INFILE      2
  35. #define ERR_BAD_HEADER  3
  36. #define ERR_G_LIB       4
  37. #define ERR_INT_LIB     5
  38. #define ERR_P_WINDOW    6
  39. #define ERR_ABORT       7
  40. #define ERR_NO_IMAGE    8
  41. #define ERR_SCREEN      9
  42. #define ERR_S_WINDOW    10
  43. #define ERR_SHORT_FILE      11
  44. #define ERR_HEADER_VERSION  12
  45. #define ERR_HEADER_FLAGS    13
  46.  
  47.  
  48.  
  49. #define MP_S_WINDOW     0
  50. #define MP_QUIT         1
  51.  
  52. /* 8.5 * 72 = 612;  11 * 72 =792 */
  53. #define DEF_DOTS_WIDE       612
  54. #define DEF_DOTS_TALL       792
  55. #define DEF_HALF_DOTS_TALL  396
  56.  
  57. /* 612 / 16 ~= 39 */
  58. #define DEF_LINE_WORDS          39
  59. #define DEF_SMALL_LINE_WORDS    20
  60. #define DEF_LINE_BYTES          78
  61. /* For now, things are rather customized to 640 by 400 screen */
  62. #define DEF_SCREEN_HEIGHT       400
  63. #define TWO_E16                 65536
  64. #define TWO_E16_MINUS_1         65535
  65. #define IMAGESIZE               DEF_LINE_WORDS*DEF_DOTS_TALL
  66. #define SMALL_IMAGESIZE         DEF_SMALL_LINE_WORDS*DEF_HALF_DOTS_TALL
  67. #define NORMALFLAGS     (WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE|WINDOWDEPTH)
  68.  
  69. extern struct WBStartup *WBenchMsg;
  70.  
  71. static char *err_msg[]=
  72. {
  73. "Everything ok.\n",
  74. "Command format:  dps infile\n\n\
  75.    Command displays a PrintScript run length encoded file.\n\n",
  76. "Input file does not exist.\n\n",
  77. "This is not a proper PrintScript file.\n\n",
  78. "Graphics library won't open!\n\n",
  79. "Intuition library won't open!\n\n",
  80. "Unable to open page display window!  Probably low on memory.\n\n",
  81. "Dps aborted.\n\n",
  82. "Unable to create image!  Probably low on memory.\n\n",
  83. "Unable to open custom screen!  Probably low on memory.\n\n",
  84. "Unable to open overview window!  Probably low on memory.\n\n",
  85. "File too short for even header.\n\n",
  86. "Version number in file header must be 1.\n\n",
  87. "Flags number in file header must be 1 (RLE).\n\n"
  88. };
  89.  
  90. int     version;
  91. int     flags;
  92. int     xdpi;
  93. int     ydpi;
  94. int     width;
  95. int     height;
  96.  
  97. int     from_wb=FALSE;
  98. int     bytes_per_line;
  99. int     max_bytes_out;
  100. int     bytes_out=0;
  101. int     field_length;
  102. int     field_count=0;
  103. int     repeat_count=0;
  104. int     data_byte=0;
  105. int     nibble=0;
  106. int     blank_line=TRUE;
  107. int     new_line[DEF_LINE_BYTES];
  108. int     page_line_count=0;
  109. int     screen_lines=DEF_SCREEN_HEIGHT;
  110. char    *con_name = "CON:20/20/600/40/ DPS  V1.1";
  111. USHORT  *image=NULL;
  112. USHORT  *small_image=NULL;
  113. USHORT  color_map[]={
  114. 0x0867, /* Gray page background to reduce flicker */
  115. 0x0000, /* Black text on paper */
  116. 0x0404, /* Dark purple */
  117. 0x0640  /* Yellow */
  118. };
  119.  
  120. struct  Image   small_page = {
  121.     0, 0,       /* LeftEdge, TopEdge */
  122.     DEF_LINE_WORDS*8, DEF_HALF_DOTS_TALL,   /* Width, Height */
  123.     1,          /* Depth */
  124.     NULL,       /* *ImageData */
  125.     1, 0,       /* PlanePick, PlaneOnOff */
  126.     NULL        /* *NextImage */
  127. };
  128.  
  129. struct  Image   page = {
  130.     -10, 0,     /* LeftEdge, TopEdge */
  131.     DEF_LINE_WORDS*16, DEF_DOTS_TALL,   /* Width, Height */
  132.     1,          /* Depth */
  133.     NULL,       /* *ImageData */
  134.     1, 0,       /* PlanePick, PlaneOnOff */
  135.     NULL        /* *NextImage */
  136. };
  137.  
  138. struct  Border  slide_border1 = {
  139.     0, 0,           /* LeftEdge, TopEdge */
  140.     1, 2, JAM1,     /* FrontPen, BackPen (ignored), DrawMode */
  141.     0,              /* Count */
  142.     NULL,       /* *XY */
  143.     NULL            /* *NextBorder */
  144. };
  145.  
  146. struct  Border  slide_border2 = {
  147.     0, 0,           /* LeftEdge, TopEdge */
  148.     1, 2, JAM1,     /* FrontPen, BackPen (ignored), DrawMode */
  149.     0,              /* Count */
  150.     NULL,       /* *XY */
  151.     NULL            /* *NextBorder */
  152. };
  153.  
  154. struct  PropInfo    prop_slider1 = {
  155.     FREEVERT | AUTOKNOB,        /* Flags */
  156.     0,                          /* HorizPot */
  157.     0,                          /* VertPot */
  158.     0xFFFF,                     /* HorizBody */
  159.     0x5555,                     /* VertBody */
  160.     0,                          /* CWidth */
  161.     0,                          /* CHeight */
  162.     0,                          /* HPotRes */
  163.     0,                          /* VPotRes */
  164.     0,                          /* LeftBorder */
  165.     0                           /* TopBorder */
  166. };
  167.  
  168. struct  PropInfo    prop_slider2 = {
  169.     FREEVERT | AUTOKNOB,        /* Flags */
  170.     0,                          /* HorizPot */
  171.     0,                          /* VertPot */
  172.     0xFFFF,                     /* HorizBody */
  173.     0x5555,                     /* VertBody */
  174.     0,                          /* CWidth */
  175.     0,                          /* CHeight */
  176.     0,                          /* HPotRes */
  177.     0,                          /* VPotRes */
  178.     0,                          /* LeftBorder */
  179.     0                           /* TopBorder */
  180. };
  181.  
  182. struct  Gadget  slider1 = {
  183.     NULL,                       /* *NextGadget */
  184.     -18, 12, 16, -25,           /* LeftEdge, TopEdge, 
  185.                                     Width, Height */
  186.     GADGHCOMP | GRELRIGHT | GRELHEIGHT,     /* Flags */
  187.     GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,    /* Activation */
  188.     PROPGADGET | GZZGADGET,     /* GadgetType */
  189.     (APTR)&slide_border1,       /* GadgetRender */
  190.     NULL,                       /* SelectRender */
  191.     NULL,                       /* *GadgetText */
  192.     0,                          /* MutualExclude */
  193.     (APTR)&prop_slider1,            /* SpecialInfo */
  194.     1,                          /* GadgetID */
  195.     NULL                        /* UserData */
  196. };
  197.  
  198. struct  Gadget  slider2 = {
  199.     NULL,                       /* *NextGadget */
  200.     -18, 12, 16, -25,           /* LeftEdge, TopEdge, 
  201.                                     Width, Height */
  202.     GADGHCOMP | GRELRIGHT | GRELHEIGHT,     /* Flags */
  203.     GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,    /* Activation */
  204.     PROPGADGET | GZZGADGET,     /* GadgetType */
  205.     (APTR)&slide_border2,       /* GadgetRender */
  206.     NULL,                       /* SelectRender */
  207.     NULL,                       /* *GadgetText */
  208.     0,                          /* MutualExclude */
  209.     (APTR)&prop_slider2,            /* SpecialInfo */
  210.     1,                          /* GadgetID */
  211.     NULL                        /* UserData */
  212. };
  213.  
  214. struct IntuiText req_text = {
  215.     0,1,                        /* FrontPen, BackPen */
  216.     JAM1,                       /* DrawMode */
  217.     5,4,                        /* LeftEdge, TopEdge */
  218.     NULL,                       /* TextAttr */
  219.     NULL,                       /* UBYTE *IText */
  220.     NULL                        /* NextText */
  221. };
  222.  
  223. struct IntuiText cont_text = {
  224.     0,1,                        /* FrontPen, BackPen */
  225.     JAM1,                       /* DrawMode */
  226.     5,4,                        /* LeftEdge, TopEdge */
  227.     NULL,                       /* TextAttr */
  228.     (unsigned char *)"Continue",/* UBYTE *IText */
  229.     NULL                        /* NextText */
  230. };
  231.  
  232. struct IntuiText p_menu_1_text = {
  233.     0,1,                        /* FrontPen, BackPen */
  234.     JAM1,                       /* DrawMode */
  235.     0,0,                        /* LeftEdge, TopEdge */
  236.     NULL,                       /* TextAttr */
  237.     (unsigned char *)"Overview",/* UBYTE *IText */
  238.     NULL                        /* NextText */
  239. };
  240.  
  241. struct IntuiText p_menu_2_text = {
  242.     0,1,                        /* FrontPen, BackPen */
  243.     JAM1,                       /* DrawMode */
  244.     0,0,                        /* LeftEdge, TopEdge */
  245.     NULL,                       /* TextAttr */
  246.     (unsigned char *)"Quit",    /* UBYTE *IText */
  247.     NULL                        /* NextText */
  248. };
  249.  
  250. struct MenuItem p_menu_2 = {
  251.     NULL,                       /* *NextItem */
  252.     0,12,80,12,                 /* LeftEdge, TopEdge, Width, Height */
  253.     ITEMTEXT | HIGHCOMP | ITEMENABLED,      /* Flags */
  254.     0,                          /* MutualExclude */
  255.     (APTR)&p_menu_2_text,       /* ItemFill */
  256.     0,                          /* Command */
  257.     NULL,                       /* *SubItem */
  258.     0                           /* NextSelect */
  259. };
  260.  
  261. struct MenuItem p_menu_1 = {
  262.     &p_menu_2,                  /* *NextItem */
  263.     0,0,80,12,                  /* LeftEdge, TopEdge, Width, Height */
  264.     ITEMTEXT | HIGHCOMP | ITEMENABLED,      /* Flags */
  265.     0,                          /* MutualExclude */
  266.     (APTR)&p_menu_1_text,       /* ItemFill */
  267.     0,                          /* Command */
  268.     NULL,                       /* *SubItem */
  269.     0                           /* NextSelect */
  270. };
  271.  
  272. struct Menu project_menu = {
  273.     NULL,                       /* *NextMenu */
  274.     0,0,80,12,                  /* LeftEdge, TopEdge, Width, Height */
  275.     MENUENABLED,                /* Flags */
  276.     (BYTE *)"Project",          /* BYTE *MenuName */
  277.     &p_menu_1                   /* *FirstItem */
  278. };
  279.  
  280. static struct NewScreen myDpsScreen = {
  281.     0, 0,                   /* SHORT LeftEdge, TopEdge */
  282.     640, DEF_SCREEN_HEIGHT, /* Width, Height */
  283.     2,                      /* Depth */
  284.     0, 1,                   /* UBYTE DetailPen, BlockPen */
  285.     HIRES | INTERLACE,      /* USHORT ViewModes */
  286.     CUSTOMSCREEN,           /* USHORT Type */
  287.     NULL,                   /* struct TextAttr *Font */
  288.     (unsigned char *)"DPS Screen", /* UBYTE *DefaultTitle */
  289.     NULL,                   /* struct Gadget *Gadgets */
  290.     NULL                    /* struct BitMap *CustomBitMap */
  291. };
  292.  
  293. static struct NewWindow myPageWindow = {
  294.     0, 0,                   /* SHORT LeftEdge, TopEdge */
  295.     640,                    /* Width */
  296.     DEF_SCREEN_HEIGHT,      /* Height */
  297.     -1, -1,                 /* UBYTE DetailPen, BlockPen */
  298.                             /* ULONG IDCMPFlags */
  299.     CLOSEWINDOW | NEWSIZE | MENUPICK | GADGETDOWN | GADGETUP | MOUSEMOVE,
  300.                             /* ULONG Flags */
  301.     SMART_REFRESH|NOCAREREFRESH|NORMALFLAGS|GIMMEZEROZERO,
  302.     &slider1,               /* struct Gadget *FirstGadget */
  303.     NULL,                   /* struct Image *CheckMark */
  304.     (unsigned char *)"DPS  V1.1", /* UBYTE *Title */
  305.     NULL,                   /* struct Screen *Screen */
  306.     NULL,                   /* struct BitMap *BitMap */
  307.     80, 50, 640, 400,       /* SHORT MinWidth,MinHeight, 
  308.                                      MaxWidth, MaxHeight*/
  309.     CUSTOMSCREEN            /* USHORT Type */
  310. };
  311.  
  312. static struct NewWindow mySmallWindow = {
  313.     0, 0,                   /* SHORT LeftEdge, TopEdge */
  314.     DEF_LINE_WORDS*8+28,    /* Width */
  315.     DEF_SCREEN_HEIGHT,      /* Height */
  316.     -1, -1,                 /* UBYTE DetailPen, BlockPen */
  317.                             /* ULONG IDCMPFlags */
  318.     CLOSEWINDOW | NEWSIZE | MENUPICK | GADGETDOWN | GADGETUP | MOUSEMOVE,
  319.                             /* ULONG Flags */
  320.     SMART_REFRESH|NOCAREREFRESH|NORMALFLAGS|GIMMEZEROZERO,
  321.     &slider2,               /* struct Gadget *FirstGadget */
  322.     NULL,                   /* struct Image *CheckMark */
  323.     (unsigned char *)"Overview", /* UBYTE *Title */
  324.     NULL,                   /* struct Screen *Screen */
  325.     NULL,                   /* struct BitMap *BitMap */
  326.     80, 50, 640, 400,       /* SHORT MinWidth,MinHeight, 
  327.                                      MaxWidth, MaxHeight*/
  328.     CUSTOMSCREEN            /* USHORT Type */
  329. };
  330.  
  331. struct  Screen      *dpsScreen=NULL;
  332. struct  Window      *pageWindow=NULL;
  333. struct  Menu        *pageWindowMenu=NULL;
  334. struct  Window      *smallWindow=NULL;
  335. struct  RastPort    *Rport1=NULL;
  336. struct  RastPort    *Rport2=NULL;
  337. struct  Library     *IconBase=NULL;
  338. struct  Library     *GfxBase=NULL;
  339. struct  Library     *IntuitionBase=NULL;
  340.  
  341.  
  342. void disp_err(x)
  343.     int x;
  344. {
  345.     struct FileHandle *con;
  346.  
  347.     if (from_wb) {
  348.         if (pageWindow) {
  349.             req_text.IText = (UBYTE *) err_msg[x];
  350.             x = AutoRequest(pageWindow,&req_text,NULL,&cont_text,
  351.                         NULL,NULL,600,60);
  352.         }
  353.         else {
  354.             con = Open(con_name,MODE_OLDFILE);
  355.             if (con) {
  356.                 Write(con,err_msg[x],strlen(err_msg[x]));
  357.                 Delay(120);
  358.                 Close(con);
  359.             }
  360.         }
  361.     }
  362.     else {
  363.         printf(err_msg[x]);
  364.     }
  365. }
  366.  
  367. void err_exit(x)
  368.     int x;
  369. {
  370.     disp_err(x);
  371.     exit(x); /* err_exit is not called when any windows/screens are open */
  372. }
  373.  
  374. void redraw_small_image()
  375. {
  376.     int     image_lines;
  377.     int     first_line;
  378.     int     last_line;
  379.  
  380.  
  381.     image_lines = smallWindow->Height - smallWindow->BorderTop -
  382.                     smallWindow->BorderBottom;
  383.     last_line = DEF_HALF_DOTS_TALL - image_lines;
  384.     first_line = (prop_slider2.VertPot * last_line)/ TWO_E16_MINUS_1;
  385.  
  386.     DrawImage(Rport2,&small_page,0,-first_line);
  387. }
  388.  
  389. void redraw_image()     /* redraws large image */
  390. {
  391.     int image_lines;
  392.     int     first_line;
  393.     int     last_line;
  394.  
  395.  
  396.     image_lines = pageWindow->Height - pageWindow->BorderTop -
  397.                     pageWindow->BorderBottom;
  398.     last_line = DEF_DOTS_TALL - image_lines;
  399.     first_line = (prop_slider1.VertPot * last_line)/ TWO_E16_MINUS_1;
  400.  
  401.     DrawImage(Rport1,&page,0,-first_line);
  402. }
  403.  
  404. void redraw_small_window() /* sets slider and redraws small image */
  405. {
  406.     int     image_lines;
  407.     int     body;
  408.     int     first_line;
  409.     int     last_line;
  410.  
  411.  
  412.     image_lines = smallWindow->Height - smallWindow->BorderTop -
  413.                     smallWindow->BorderBottom;
  414.     body = (TWO_E16_MINUS_1 * image_lines) / DEF_HALF_DOTS_TALL;
  415.     last_line = DEF_HALF_DOTS_TALL - image_lines;
  416.     first_line = (prop_slider2.VertPot * last_line)/ TWO_E16_MINUS_1;
  417.  
  418.     DrawImage(Rport2,&small_page,0,-first_line);
  419.     ModifyProp(&slider2,smallWindow,NULL,prop_slider2.Flags,
  420.         prop_slider2.HorizPot,prop_slider2.VertPot,prop_slider2.HorizBody,
  421.         body);
  422.     RefreshGadgets(&slider2,smallWindow,NULL);
  423. }
  424.  
  425. void redraw()   /* sets slider and redraws large image */
  426. {
  427.     int     image_lines;
  428.     int     body;
  429.     int     first_line;
  430.     int     last_line;
  431.  
  432.  
  433.     image_lines = pageWindow->Height - pageWindow->BorderTop -
  434.                     pageWindow->BorderBottom;
  435.     body = (TWO_E16_MINUS_1 * image_lines) / DEF_DOTS_TALL;
  436.     last_line = DEF_DOTS_TALL - image_lines;
  437.     first_line = (prop_slider1.VertPot * last_line)/ TWO_E16_MINUS_1;
  438.  
  439.     DrawImage(Rport1,&page,0,-first_line);
  440.     ModifyProp(&slider1,pageWindow,NULL,prop_slider1.Flags,
  441.         prop_slider1.HorizPot,prop_slider1.VertPot,prop_slider1.HorizBody,
  442.         body);
  443.     RefreshGadgets(&slider1,pageWindow,NULL);
  444. }
  445.  
  446. void kill_small_window()
  447. {
  448.     if (small_image != NULL) {
  449.         FreeMem(small_image, SMALL_IMAGESIZE*sizeof(USHORT));
  450.         small_image = NULL;
  451.     }
  452.     if (smallWindow) {
  453.         CloseWindow(smallWindow);
  454.         smallWindow = NULL;
  455.     }
  456.     Rport2=NULL;
  457. }
  458.  
  459. void open_small_window()
  460. {
  461.     int i,j,k;
  462.     int big_words;
  463.     int small_words;
  464.  
  465.     if (smallWindow == NULL) {
  466.  
  467.         small_image = (USHORT *) AllocMem(SMALL_IMAGESIZE*sizeof(USHORT), 
  468.                                             MEMF_CHIP|MEMF_CLEAR);
  469.         if (small_image == NULL) {
  470.             disp_err(ERR_NO_IMAGE);
  471.             return;
  472.         }
  473.         small_page.ImageData = small_image;
  474.  
  475.         big_words =0;   /* Offset to present row in page image */
  476.         small_words=0;  /* Offset to present row in small image */
  477.  
  478.         /* The following loop compresses the image 2x in both
  479.             height and width */
  480.  
  481.         for (i = 0; i<DEF_HALF_DOTS_TALL; i++) {
  482.             for (j = 0, k=0; j<DEF_SMALL_LINE_WORDS-1; j++, k += 2) {
  483.                 small_image[small_words+j] = 
  484.                     (shrink_word(image[big_words+k])<<8) + 
  485.                     shrink_word(image[big_words+k+1]);
  486.                 small_image[small_words+j] |= 
  487.                     (shrink_word(image[big_words+k+DEF_LINE_WORDS])<<8) + 
  488.                     shrink_word(image[big_words+k+DEF_LINE_WORDS+1]);
  489.             }
  490.             small_image[small_words+j] =  (shrink_word(image[big_words+k])
  491.                     |  shrink_word(image[big_words+k+DEF_LINE_WORDS])) <<8;
  492.             big_words += 2*DEF_LINE_WORDS;
  493.             small_words += DEF_SMALL_LINE_WORDS;
  494.         }
  495.  
  496.         prop_slider2.VertPot = 0; /* This is needed on second opening of
  497.                                      this window */
  498.         smallWindow = OpenWindow(&mySmallWindow);
  499.         Rport2 = smallWindow->RPort;
  500.         if (smallWindow == NULL) {
  501.             kill_small_window();
  502.             disp_err(ERR_S_WINDOW);
  503.             return;
  504.         }
  505.         redraw_small_window();
  506.     }
  507. }
  508.  
  509. void kill_page_window()
  510. {
  511.     if (image) {
  512.         FreeMem(image, IMAGESIZE*sizeof(USHORT));
  513.         image = NULL;
  514.     }
  515.     if (pageWindow) {
  516.         if (pageWindowMenu) ClearMenuStrip(pageWindow);
  517.         pageWindowMenu = NULL;
  518.         CloseWindow(pageWindow);
  519.         pageWindow = NULL;
  520.     }
  521. }
  522.  
  523. void kill_dps_screen()
  524. {
  525.     kill_small_window();
  526.     kill_page_window();
  527.     if (dpsScreen) {
  528.         CloseScreen(dpsScreen);
  529.         dpsScreen == NULL;
  530.     }
  531. }
  532.  
  533. void open_page_window()
  534. {
  535.     myPageWindow.Screen = dpsScreen;
  536.     mySmallWindow.Screen = dpsScreen;
  537.  
  538.     pageWindow = OpenWindow(&myPageWindow);
  539.     if (pageWindow == NULL) {
  540.         kill_dps_screen();
  541.         CloseLibrary(IntuitionBase);
  542.         CloseLibrary(GfxBase);
  543.         err_exit(ERR_P_WINDOW);
  544.     }
  545.  
  546.     pageWindowMenu = &project_menu;
  547.     SetMenuStrip(pageWindow, pageWindowMenu);
  548.     Rport1 = pageWindow->RPort;
  549.     redraw();
  550. }
  551.  
  552. void handle_events()
  553. {
  554.     int     mouse_moved;
  555.     int     remove_small_window;
  556.     int     make_small_window;
  557.     int     get_out;
  558.     struct  IntuiMessage *imsg;
  559.     long    class;
  560.     USHORT  code;
  561.     unsigned long m1, m2, res;
  562.     short   menu, item;
  563.  
  564.     m1=1L<<pageWindow->UserPort->mp_SigBit;
  565.     m2=0;
  566.     for (;;)  {
  567.         res = Wait(m1|m2);
  568.         if (res & m1) {
  569.             get_out=FALSE;
  570.             mouse_moved=FALSE;
  571.             make_small_window=FALSE;
  572.             while (imsg = (struct IntuiMessage *)GetMsg(pageWindow->UserPort)) {
  573.                 class = imsg->Class;
  574.                 code = imsg->Code;
  575.                 ReplyMsg(imsg);
  576.                 switch(class) {
  577.                     case CLOSEWINDOW:
  578.                         get_out=TRUE;
  579.                         break;
  580.                     case NEWSIZE:
  581.                         redraw(); 
  582.                         break;
  583.                     case GADGETDOWN:    /* Gadget stuff all the same */
  584.                     case GADGETUP:
  585.                     case MOUSEMOVE:
  586.                         mouse_moved = TRUE;
  587.                         break;
  588.                     case MENUPICK:
  589.                         menu = MENUNUM(code);
  590.                         item = ITEMNUM(code);
  591.                         if (menu == 0) {
  592.                             switch(item) {
  593.                                 case(MP_S_WINDOW):
  594.                                     make_small_window=TRUE;
  595.                                     break;
  596.                                 case(MP_QUIT):
  597.                                     get_out=TRUE;
  598.                                     break;
  599.                                 default:
  600.                                     break;
  601.                             }
  602.                         }
  603.                         break;
  604.                     default:
  605.                         break;
  606.                 }
  607.             }
  608.             if (get_out) return;
  609.             if (mouse_moved) redraw_image();
  610.             if (make_small_window) {
  611.                 open_small_window();
  612.                 if (smallWindow) m2=1L<<smallWindow->UserPort->mp_SigBit;
  613.             }
  614.         }
  615.         if (res & m2) {
  616.             mouse_moved = FALSE;
  617.             remove_small_window = FALSE;
  618.             while (imsg = (struct IntuiMessage *)GetMsg(smallWindow->UserPort)) {
  619.                 class = imsg->Class;
  620.                 code = imsg->Code;
  621.                 ReplyMsg(imsg);
  622.                 switch(class) {
  623.                     case CLOSEWINDOW:
  624.                         remove_small_window = TRUE;
  625.                         break;
  626.                     case NEWSIZE:
  627.                         redraw_small_window(); 
  628.                         break;
  629.                     case GADGETDOWN:    /* Gadget stuff all the same */
  630.                     case GADGETUP:
  631.                     case MOUSEMOVE:
  632.                         mouse_moved = TRUE;
  633.                         break;
  634.                     default:
  635.                         break;
  636.                 }
  637.             }
  638.             if (remove_small_window) {
  639.                 kill_small_window();
  640.                 m2 = 0;
  641.             }
  642.             else if (mouse_moved) redraw_small_image();
  643.         }
  644.     }
  645. }
  646.  
  647. int shrink_byte(c)  /* Compress a byte into a nibble.  
  648.                         This routine not used at present, 
  649.                         but might be useful */
  650.     int c;
  651. {
  652.     int nibble;
  653.  
  654.     nibble = 0;
  655.     if (c & 3) nibble = 1;
  656.     if (c & 12) nibble |= 2;
  657.     if (c & 48) nibble |= 4;
  658.     if (c & 192) nibble |= 8;
  659.     return(nibble);
  660. }
  661.  
  662. int shrink_word(c)  /* Compress a 16 bit word into 8 bits */
  663.     unsigned int c;
  664. {
  665.     unsigned int byte;
  666.  
  667.     byte = 0;
  668.     if (c & 0x3)    byte = 1;
  669.     if (c & 0xc)    byte |= 2;
  670.     if (c & 0x30)   byte |= 4;
  671.     if (c & 0xc0)   byte |= 8;
  672.     if (c & 0x300)  byte |= 0x10;
  673.     if (c & 0xc00)  byte |= 0x20;
  674.     if (c & 0x3000) byte |= 0x40;
  675.     if (c & 0xc000) byte |= 0x80;
  676.     return(byte);
  677. }
  678.  
  679. void clear_new_line()
  680. {
  681.     int j;
  682.  
  683.     for (j = 0; j<DEF_LINE_BYTES; j++) {
  684.         new_line[j] = 0;
  685.     }
  686. }
  687.  
  688. int flip_byte(c)    /* Reverses the bit order */
  689.     int c;
  690. {
  691.     int b;
  692.  
  693.     b = ((c & 1) <<7) | ((c & 2) <<5) | ((c & 4) <<3) | ((c & 8) <<1);
  694.     b |= ((c & 0x80) >>7) | ((c & 0x40) >>5) | ((c & 0x20) >>3) | 
  695.          ((c & 0x10) >>1);
  696.     return(b);
  697. }
  698.  
  699. void clear_image() /* Sets up large image.  Draws a (8.5 x 11) page 
  700.                         border into the image. */
  701. {
  702.     int i;
  703.     int j;
  704.  
  705.     image = (USHORT *) AllocMem(IMAGESIZE*sizeof(USHORT), 
  706.                                 MEMF_CHIP|MEMF_CLEAR);
  707.     if (image == NULL) {
  708.         err_exit(ERR_NO_IMAGE);
  709.     }
  710.     page.ImageData = image;
  711.  
  712.     /* Draw a page border */
  713.     i = (DEF_DOTS_TALL-1) * DEF_LINE_WORDS; /* point to last line */
  714.     for (j = 1; j<DEF_LINE_WORDS; j++) {
  715.         image[j] = 0xFFFF;
  716.         image[i+j] = 0xFFFF;
  717.     }
  718.     image[0] = 0x000F; /* 8.5inches * 72dpi = 612 bits 
  719.                         = 38.25 (16bit words)
  720.                         Therefore, we need 39 words.
  721.                         Since the line is flipped, data starts on the
  722.                         third nibble */
  723.     image[i] = 0x000F;
  724.     for (j = 1, i=DEF_LINE_WORDS; 
  725.         j<DEF_DOTS_TALL-1; j++, i += DEF_LINE_WORDS) {
  726.  
  727.         image[i] = 0x0008;                  /* Beginning of line */
  728.         image[i+DEF_LINE_WORDS-1] = 0x0001; /* End of line */
  729.     }
  730. }
  731.  
  732. void enter_new_line()   /* puts a line into the large image */
  733. {
  734.     int b;
  735.     int i;
  736.     int j;
  737.     int k;
  738.  
  739.     page_line_count++;
  740.     if (page_line_count > DEF_DOTS_TALL) return;
  741.     if (blank_line != TRUE) {
  742.         k = (DEF_DOTS_TALL-page_line_count)*DEF_LINE_WORDS;
  743.         for (b=j= 0; j<DEF_LINE_WORDS; j++, b += 2) {
  744.             i = (new_line[b]<<8) + new_line[b+1];
  745.             image[k+j] ^= i; /* XOR so that writes on page edges are
  746.                                 visible */
  747.         }
  748.     }
  749.     blank_line = TRUE;
  750. }
  751.  
  752. void read_header()  /* Reads the header of a PrintScript run-length-encoded
  753.                         file. */
  754. {
  755.     int     c;
  756.     int     i;
  757.     int     done;
  758.  
  759.  
  760.     /* Read header and check if ok */
  761.     done = FALSE;
  762.     i=0;
  763.     while (done != TRUE) {
  764.         c = getc(ifile);
  765.         if (c == EOF) {
  766.             done = TRUE;
  767.             disp_err(ERR_SHORT_FILE);
  768.             err_exit(ERR_BAD_HEADER);
  769.         }
  770.         else {
  771.             i++;
  772.             switch (i) {
  773.                 case 1:
  774.                     version = c*256;
  775.                     break;
  776.                 case 2:
  777.                     version += c;
  778.                     /* This needs to be re-thought if future versions
  779.                         come along. */
  780.                     if (version != 1) {
  781.                         disp_err(ERR_HEADER_VERSION);
  782.                         err_exit(ERR_BAD_HEADER);
  783.                     }
  784.                     break;
  785.                 case 3:
  786.                     flags = c*256;
  787.                     break;
  788.                 case 4:
  789.                     flags += c;
  790.                     if (flags != 1) {
  791.                         disp_err(ERR_HEADER_FLAGS);
  792.                         err_exit(ERR_BAD_HEADER);
  793.                     }
  794.                     break;
  795.                 case 5:
  796.                     xdpi = c*256;
  797.                     break;
  798.                 case 6:
  799.                     xdpi += c;
  800.                     break;
  801.                 case 7:
  802.                     ydpi = c*256;
  803.                     break;
  804.                 case 8:
  805.                     ydpi += c;
  806.                     break;
  807.                 case 9:
  808.                     width = c*256;
  809.                     break;
  810.                 case 10:
  811.                     width += c;
  812.                     break;
  813.                 case 11:
  814.                     height = c*256;
  815.                     break;
  816.                 case 12:
  817.                     height += c;
  818.                     done = TRUE;
  819.                     break;
  820.                 default:
  821.                     err_exit(ERR_BAD_HEADER); /* Should never get here */
  822.                     break;
  823.             }
  824.         }
  825.     }
  826.  
  827. }
  828.  
  829. void build_image()  /* This reads the part of the PrintScript
  830.                         run-length-encoded file and builds the image.
  831.                         Since the PrintScript image is "upside-down",
  832.                         we need to put the top line to the bottom, etc.,
  833.                         and also reverse each line left-to-right. */
  834. {
  835.     int     c;
  836.     int     i;
  837.     int     j;
  838.     int     done;
  839.  
  840.     clear_new_line();
  841.     blank_line = TRUE;
  842.     done = FALSE;
  843.     i=0;
  844.     while (done != TRUE) {
  845.         c = getc(ifile);
  846.         if (c == EOF) {
  847.             done = TRUE;
  848.         }
  849.         else {
  850.             i++;
  851.             switch (i) {
  852.                 case 1:
  853.                     field_length = c*256;
  854.                     field_count = 0;
  855.                     bytes_out = 0;
  856.                     break;
  857.                 case 2:
  858.                     field_length += c;
  859.                     if (field_length == 0) {
  860.                         i = 0;
  861.                         enter_new_line();   /* enter a blank line */
  862.                         /* clear_new_line(); */
  863.                     }
  864.                     else blank_line = FALSE;
  865.                     break;
  866.                 case 3:
  867.                     repeat_count = c + 1;
  868.                     field_count++;
  869.                     break;
  870.                 case 4:
  871.                     i = 2;
  872.                     data_byte = flip_byte(c); /* Reverse byte left-to-right */
  873.                     field_count++;
  874.                     if ((repeat_count + bytes_out) > max_bytes_out) {
  875.                         repeat_count = max_bytes_out - bytes_out;
  876.                     }
  877.                     for (j = 0; j<repeat_count; j++) {
  878.                         /* Put bytes in "backwards".  We want the first
  879.                             byte to go way over to the right in 
  880.                             new_line[77]. */
  881.                         bytes_out++;
  882.                         new_line[DEF_LINE_BYTES-bytes_out] = data_byte;
  883.                     }
  884.                     if (field_count >= field_length) {
  885.                         i = 0;
  886.                         enter_new_line();
  887.                         clear_new_line();
  888.                     }
  889.                     break;
  890.                 default:
  891.                     err_exit(ERR_BAD_HEADER); /* Should never get here */
  892.                     break;
  893.             }
  894.         }
  895.     }
  896.  
  897. }
  898.  
  899. void get_wb_args(wb_msg)
  900.     struct WBStartup    *wb_msg;
  901. {
  902.     struct WBArg        *wb_arg;
  903.     struct DiskObject   *diskobj;
  904.     char                **toolarray;
  905.     int                 i;
  906.     char                *s;
  907.  
  908.     wb_arg = wb_msg->sm_ArgList;
  909.     if ((IconBase = OpenLibrary("icon.library",0))) {
  910.         diskobj = (struct DiskObject *) GetDiskObject(wb_arg->wa_Name);
  911.         if (diskobj) {
  912.             toolarray = (char **) diskobj->do_ToolTypes;
  913.             s = (char *) FindToolType(toolarray,"FILE");
  914.             if (s) {
  915.                 ifile=fopen(s,"r");
  916.             }
  917.             FreeDiskObject(diskobj);
  918.         }
  919.         CloseLibrary(IconBase);
  920.     }
  921.     if (!ifile) {
  922.         err_exit(ERR_INFILE);
  923.     }
  924. }
  925.  
  926. main(argc,argv)
  927.     int argc;
  928.     char *argv[];
  929. {
  930.     struct ViewPort *vp;
  931.  
  932.     from_wb = (argc == 0);
  933.  
  934.     if (from_wb) {
  935.         get_wb_args(WBenchMsg);
  936.     }
  937.     else {
  938.         if (argc <= ARG_REQ_NUM) {
  939.             err_exit(ERR_NUM_ARGS);
  940.         }
  941.         ifile=fopen(argv[ARG_INFILE],"r");
  942.         if (!ifile) {
  943.             err_exit(ERR_INFILE);
  944.         }
  945.     }
  946.  
  947.     max_bytes_out = DEF_LINE_BYTES;
  948.  
  949.     read_header(); 
  950.  
  951.     /* Old debug stuff
  952.     printf("version = %d\n", version);
  953.     printf("flags   = %d\n", flags);
  954.     printf("xdpi    = %d\n", xdpi);
  955.     printf("ydpi    = %d\n", ydpi);
  956.     printf("width   = %d\n", width);
  957.     printf("height  = %d\n", height);
  958.     printf("max_bytes_out  = %d\n", max_bytes_out);
  959.     */
  960.  
  961.     clear_image();
  962.     build_image();
  963.     close(ifile);
  964.  
  965.     /* If we haven't aborted by this point, start doing graphics */
  966.  
  967.     GfxBase = OpenLibrary("graphics.library", 0L);
  968.     if (GfxBase == NULL) { 
  969.         if (image != NULL) {
  970.             FreeMem(image, IMAGESIZE*sizeof(USHORT));
  971.             image = NULL;
  972.         }
  973.         err_exit(ERR_G_LIB); 
  974.     }
  975.     IntuitionBase = OpenLibrary("intuition.library", 0L);
  976.     if (IntuitionBase == NULL) {
  977.         if (image != NULL) {
  978.             FreeMem(image, IMAGESIZE*sizeof(USHORT));
  979.             image = NULL;
  980.         }
  981.         CloseLibrary(GfxBase);
  982.         err_exit(ERR_INT_LIB);
  983.     }
  984.  
  985.     dpsScreen = OpenScreen(&myDpsScreen);
  986.     if (dpsScreen == NULL) {
  987.         kill_dps_screen();
  988.         CloseLibrary(IntuitionBase);
  989.         CloseLibrary(GfxBase);
  990.         err_exit(ERR_SCREEN);
  991.     }
  992.     vp = &dpsScreen->ViewPort;
  993.     LoadRGB4(vp,color_map,4);
  994.  
  995.     open_page_window();
  996.     handle_events();
  997.  
  998.     kill_dps_screen();
  999.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  1000.     if (GfxBase) CloseLibrary(GfxBase);
  1001.     return(0);
  1002. }
  1003.  
  1004.  
  1005. _abort()
  1006. {
  1007.     kill_dps_screen();
  1008.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  1009.     if (GfxBase) CloseLibrary(GfxBase);
  1010.     exit(ERR_ABORT);
  1011. }
  1012.  
  1013.  
  1014.